package com.jlf.tool.toolkit;

/**
 * 位运算辅助工具
 *
 * @author wujr
 * 2023/7/19
 * @version 1.0
 * 【变更历史】
 * [wujr 2023/7/19 1.0 新增]
 */
public class BitToolkit {
    /**
     * 判断某位的值是否为1
     * @param value 需要判断的值
     * @param bit 第n位，从0开始
     * @return true表示该位为1
     */
    public static boolean isBit(int value ,int bit){
        return ((value >> bit) & 1) != 0;
    }
    public static boolean isBit(long value ,int bit){
        return ((value >> bit) & 1L) != 0;
    }
    /**
     * 设置位
     * @param value 需要设置的值
     * @param bit 第n位，从0开始
     * @return 设置后的值
     */
    public static int set(int value, int bit){
        return value |= (1 << bit);
    }

    /**
     * 清理位
     * @param value 要清理的值
     * @param bit 第n位，从0开始
     * @return 清理后的值
     */
    public static int clean(int value, int bit){
        return value &= (~(1 << bit));
    }
    /**
     * 设置位
     * @param value 需要设置的值
     * @param bit 第n位，从0开始
     * @return 设置后的值
     */
    public static long set(long value, int bit){
        return value |= (1L << bit);
    }

    /**
     * 清理位
     * @param value 要清理的值
     * @param bit 第n位，从0开始
     * @return 清理后的值
     */
    public static long clean(long value, int bit){
        return value &= (~(1L << bit));
    }

    /**
     * 找到数组中仅出现一次的数字
     * @param numbers 数组
     * @return 仅出现一次的数字
     */
    public static int single(int[] numbers){
        int number = 0;
        for (int j : numbers) {
            number = number ^ j;
        }
        return number;
    }
    public static long single(long[] numbers){
        long number = 0;
        for (long j : numbers) {
            number = number ^ j;
        }
        return number;
    }

    /**
     * 计算两个数字的汉明距离
     * 两个整数之间的汉明距离指的是：这两个整数的对应二进制位不相同的位的数量
     * 例如：
     * 输入：a = 1, b = 4
     * 输出：2
     * 解释：
     * a = 1 (0 0 0 1)
     * b = 4 (0 1 0 0)
     *          ^   ^
     * 上面的箭头指出了二进制位不同的位置，一共有2个二进制位不同
     * @param a 数字1
     * @param b 数字2
     * @return 汉明距离
     */
    public static int hamming(int a, int b){
        int n = a ^ b;
        int number = 0;
        while(n != 0){
            n &= (n - 1);
            ++ number;
        }
        return number;
    }
}
